/**
 * Copyright (c) 2016,http://www.365wuliu.com/  All Rights Reserved.
 */
package com.cargo.security;

import com.cargo.base.exceptions.ExceptionVo;
import com.cargo.base.utils.CheckUtil;
import com.cargo.base.utils.PropertiesUtil;
import com.mysql.jdbc.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * UsersFilter:shiro权限过滤器，验证用户是否被授权  (这个的过滤器的主要作用是 : 后期 调用接口的时候会 检查前台传回的Authorization 是否符合凭证,保证调用接口安全)
 * @Project Name:cargo
 * @File Name:UsersFilter.java
 * @Package Name:com.cargo.security
 * @Creator:ZHU CHEN
 * @Date:2016年4月14日下午2:25:43
 */
public class UsersFilter extends PathMatchingFilter {

	@Override
	public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
		HttpServletRequest req = WebUtils.toHttp(request);
		HttpServletResponse res = WebUtils.toHttp(response);
		Subject subject = SecurityUtils.getSubject();
		try {
			if (req.getMethod().equals("OPTIONS")) {
				res.addHeader("Access-Control-Allow-Headers",
						"x-requested-with, content-type, accept, origin, Authorization, x-csrftoken, user-agent, accept-encoding, timestamp, signature, platform, cache-control, pragma, If-Modified-Since, sys_source");
				res.addHeader("Access-Control-Allow-Origin", "*");
				res.addHeader("Access-Control-Allow-Methods", "GET, POST,OPTIONS");
				return false;
			} else {
				res.addHeader("Access-Control-Allow-Origin", "*");
				
				String apiKey = null;
				String sysSource = null;
				// 取得请求来源
				sysSource = req.getHeader("sys_source");
				if (StringUtils.isNullOrEmpty(sysSource)) {
					sysSource = req.getParameter("sys_source");
				}
				// ApiKey
				apiKey = req.getHeader("Authorization");
				if (StringUtils.isNullOrEmpty(apiKey)) {
					apiKey = req.getParameter("Authorization");
				}
				//ApiKey不为空，可执行后续操作，ApiKey为空，用户登出
				if (!StringUtils.isNullOrEmpty(apiKey)) {
					apiKey = apiKey.trim();
					String pwd = PropertiesUtil.getValue("api_key");
					UsernamePasswordToken token = new UsernamePasswordToken(apiKey, pwd);
					subject.login(token);
					
					// 从Shiro中获取登录对象判断访问系统与登录系统是否匹配
					ShiroUser shiroUser = (ShiroUser) subject.getPrincipal();
					if(!checkSys(shiroUser, sysSource)){
						subject.logout();
						new ExceptionVo(401, "02", "登录系统不匹配", res);
						return false;
					}
				} else {
					subject.logout();
				}
				
				//获取公司ID，部分情况下companyId需特殊处理
				if (CheckUtil.isNotEmpty(sysSource)) {
					// 根据域名查询公司ID
					Integer companyId = getCompanyId(req);
					if (CheckUtil.isNotNull(companyId)) {
						req.getSession().setAttribute("companyId", companyId);
					} else {
						new ExceptionVo(401, "01", "无匹配公司", res);
						return false;
					}
				}
				
				return true;
			}
		} catch (Exception e) {
			subject.logout();
			return true;
		}
	}
	
	/**
	 * 
	 * getCompanyId:(根据公司域名获得公司ID).
	 * @param req
	 * @return
	 * @throws Exception
	 * @return :Integer
	 * @Creator:GUO CHUN
	 * @Date:2016年8月10日 上午9:43:45
	 */
	private Integer getCompanyId(HttpServletRequest req) throws Exception {
		// 获得域名
		String webSite = req.getRequestURL().toString();
		
		webSite = webSite.split("/")[2];
		if (webSite.contains(":")) {
			webSite = webSite.split(":")[0];
		}
		// 根据域名查询公司ID
		//TODO
//		Integer companyId = sysAdminCompanyService.queryCompanyByWebSite(webSite);
		Integer companyId = 0;
		
		return companyId;
	}
	
	/**
	 * 
	 * checkSys:(判断登录访问系统与登录系统是否匹配).
	 * 
	 * @param shiroUser
	 * @param sysSource
	 * @return
	 * @throws Exception
	 * @return :boolean
	 * @Creator:GUO CHUN
	 * @Date:2016年8月10日 上午9:44:15
	 */
	private boolean checkSys(ShiroUser shiroUser, String sysSource) throws Exception {
		if (shiroUser.getSysType().intValue() == 0) {
			return true;
		}
		String commsyssource = PropertiesUtil.getValue("common.syssource." + sysSource);
		if (CheckUtil.isNotEmpty(commsyssource)) {
			String syseType = commsyssource.split(":")[1];
			if (CheckUtil.checkObj(shiroUser) && CheckUtil.checkObj(shiroUser.getSysType())) {
				if (shiroUser.getSysType().intValue() != Integer.parseInt(syseType)) {
					return false;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
		return true;
	}
}
